package com.yfqy.admin.filter;

import cn.hutool.core.bean.BeanUtil;
import com.yfqy.admin.security.login.LoginUserInfo;
import com.yfqy.admin.util.AuthUserContext;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Objects;

@Component
public class AuthUserContextFilter implements Filter {

    private static final Logger log = LoggerFactory.getLogger(AuthUserContextFilter.class);

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {
        try {
            HttpServletRequest request = (HttpServletRequest) servletRequest;
            // 如果是multipart请求，直接放行，由后续处理器处理
            if (isMultipartRequest(request)) {
                filterChain.doFilter(servletRequest, servletResponse);
                return;
            }
            if (!isApiInternalUrl(request)) {
                filterChain.doFilter(servletRequest, servletResponse);
                return;
            }
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            Object principal = Objects.isNull(authentication) ? null : authentication.getPrincipal();
            LoginUserInfo loginUserInfo = Objects.isNull(principal) ? null : BeanUtil.toBean(principal, LoginUserInfo.class);
            AuthUserContext.setLocalAuthUser(loginUserInfo);
            filterChain.doFilter(servletRequest, servletResponse);
        } finally {
            AuthUserContext.clearLocalAuthUser();
        }
    }

    /**
     * 文件上传直接放行
     *
     * @param request
     * @return
     */
    private boolean isMultipartRequest(HttpServletRequest request) {
        return request.getContentType() != null
                && request.getContentType().startsWith("multipart/form-data");
    }

    /**
     * PC端接口
     *
     * @param request
     * @return
     */
    private boolean isApiInternalUrl(HttpServletRequest request) {
        return request.getRequestURI().contains("/api/internal");
    }
}
